{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "6c6ee429-5ae7-46df-b1f7-e8f913195056",
   "metadata": {},
   "outputs": [],
   "source": [
    "\"\"\"\n",
    "思路：\n",
    "1、数据集读取,数据处理及训练集和测试集划分\n",
    "2、选取不同分布的朴素贝叶斯模型进行分类模型训练与测试、评价\n",
    "\"\"\"\n",
    "import pandas as pd\n",
    "import warnings\n",
    "\n",
    "from sklearn.feature_extraction.text import TfidfVectorizer  # 文本型数据处理\n",
    "from sklearn.preprocessing import LabelEncoder  # 字符串型数据编码\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.model_selection import cross_val_score\n",
    "from sklearn.naive_bayes import GaussianNB, BernoulliNB, MultinomialNB\n",
    "from sklearn.metrics import roc_curve, auc\n",
    "from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score\n",
    "\n",
    "from matplotlib import rcParams\n",
    "import matplotlib\n",
    "# matplotlib.use(\"Agg\")  # 输出时不显示绘图\n",
    "import matplotlib.pyplot as plt  # matplotlib.use('agg')必须在本句执行前运行\n",
    "\n",
    "rcParams['font.family'] = 'simhei'  # 可以让图像中显示中文（黑体），无需引用\n",
    "rcParams['axes.unicode_minus'] = False  # 解决负数坐标显示问题\n",
    "warnings.filterwarnings('ignore')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "87ce0f3e-4dd5-4133-b415-3a1a81542fab",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 公共部分：分类模型评价体系evaluation\n",
    "# todo: 构建分类模型的评价体系并存储在evaluation中，方便对比查看，全局变量\n",
    "evaluation = pd.DataFrame({'Model': [],\n",
    "                           '准确率': [],\n",
    "                           '精确率': [],\n",
    "                           '召回率': [],\n",
    "                           'F1 值': [],\n",
    "                           'AUC值': [],\n",
    "                           '5折交叉验证的score': []})"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9c333bc7-7828-4c18-8769-cdc91d37f71f",
   "metadata": {},
   "source": [
    "#### 一、数据读取、单词文本处理及标签数值化处理，数据集划分"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "2cd43a16-b2b3-4c51-8c5d-91a2185515f1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "           0                       1\n",
      "count   5572                    5572\n",
      "unique     2                    5169\n",
      "top      ham  Sorry, I'll call later\n",
      "freq    4825                      30\n"
     ]
    }
   ],
   "source": [
    "#1.1 读取数据\n",
    "df = pd.read_csv('./data/SMSSpamCollection', delimiter='\\t', header=None)  # 利用pandas直接读取已有数据，数据以tab分割\n",
    "print(df.describe())  # 了解数据的基本信息"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "a06a5102-2ad9-4a83-ba73-f28018beca3d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "         0                                                  1\n",
      "0      ham  Go until jurong point, crazy.. Available only ...\n",
      "1      ham                      Ok lar... Joking wif u oni...\n",
      "2     spam  Free entry in 2 a wkly comp to win FA Cup fina...\n",
      "3      ham  U dun say so early hor... U c already then say...\n",
      "4      ham  Nah I don't think he goes to usf, he lives aro...\n",
      "...    ...                                                ...\n",
      "5567  spam  This is the 2nd time we have tried 2 contact u...\n",
      "5568   ham               Will ü b going to esplanade fr home?\n",
      "5569   ham  Pity, * was in mood for that. So...any other s...\n",
      "5570   ham  The guy did some bitching but I acted like i'd...\n",
      "5571   ham                         Rofl. Its true to its name\n",
      "\n",
      "[5572 rows x 2 columns]\n"
     ]
    }
   ],
   "source": [
    "print(df)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "cfd6e939-19e0-4042-aba0-bb5236b0f8a7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "为spam短信数量： 747\n",
      "为ham短信数量： 4825\n"
     ]
    }
   ],
   "source": [
    "print('为spam邮件数量：', df[df[0] == 'spam'][0].count())\n",
    "print('为ham邮件数量：', df[df[0] == 'ham'][0].count())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "d60214c3-ee20-4102-824a-81bf502980f0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "8713\n"
     ]
    }
   ],
   "source": [
    "# 1.2 对数据集中单词文本进行处理\n",
    "# 由于数据集为单词文本数据，构建TfidfVectorizer来计算每个单词的TF-IDF权重\n",
    "tfidf_vectorizer = TfidfVectorizer()\n",
    "X = tfidf_vectorizer.fit_transform(df[1])\n",
    "X = X.toarray()  # 将数据矩阵转化为数组\n",
    "voc = tfidf_vectorizer.get_feature_names_out()\n",
    "print(len(voc))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "96fbff7a-9454-4ee3-a01e-08776384b881",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0., 0., 0., ..., 0., 0., 0.],\n",
       "       [0., 0., 0., ..., 0., 0., 0.],\n",
       "       [0., 0., 0., ..., 0., 0., 0.],\n",
       "       ...,\n",
       "       [0., 0., 0., ..., 0., 0., 0.],\n",
       "       [0., 0., 0., ..., 0., 0., 0.],\n",
       "       [0., 0., 0., ..., 0., 0., 0.]])"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "2a48c8d8-51f2-4e0f-9c0e-3bfcff0bda90",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array(['00', '000', '000pes', ..., 'èn', 'ú1', '〨ud'], dtype=object)"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "voc"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "7e575301-82ab-47e7-a134-9aeda56b7af3",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 1.3 目标变量中为字符串型数据，使用labelEncoder处理（spam-1，ham-0）\n",
    "le = LabelEncoder()  # 对定型特征多值化\n",
    "y = le.fit_transform(df[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "80dbe234-eebd-46aa-b5ae-f9f42fd42dc7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5572"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "58775bdd-51da-492d-99e8-2001fa906a62",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 1.4 对整体数据按照train_size进行划分，得到训练集和测试集, random_state确保结果的一致性\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.67, random_state=0)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "44cf9e1e-36b1-48cb-899a-c9c2c3826dc2",
   "metadata": {},
   "source": [
    "#### 二、进行朴素贝叶斯分类模型训练与测试、评价"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "308fdb0b-6e55-4d94-99b3-3ee3b27d1a11",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 2.1 创建朴素贝叶斯模型\n",
    "# GaussianNB() 高斯分布\n",
    "model = GaussianNB()\n",
    "model_name = \"GaussianNB\"\n",
    "model.fit(X_train,y_train)\n",
    "y_test_predict = model.predict(X_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "caf8e405-83e9-471f-a2d7-5ef6e4f4ed74",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 1, 0, ..., 0, 0, 0])"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_test_predict"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "14cd9021-df31-46d2-b8d4-3aa8b746bfc0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 1, 0, ..., 0, 0, 0])"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "212342d2-f2ff-4a82-b2fd-a0efa87f7126",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 2.2 todo: 计算分类评价指标：测试集的准确率accuracy、精确率precision、召回率recall和综合评价指标 F1 值\n",
    "# 精确率是指分类器预测出的垃圾短信中真的是垃圾短信的比例\n",
    "# 召回率是所有真的垃圾短信被分类器正确找出来的比例\n",
    "# F1 值是精确率和召回率的调和均值\n",
    "acc_test = accuracy_score(y_test, y_test_predict)  # 和模型自带的score一致\n",
    "precision_test = precision_score(y_test, y_test_predict)\n",
    "recall_test = recall_score(y_test, y_test_predict)\n",
    "f1score_test = f1_score(y_test, y_test_predict)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "bed8ab7d-dce7-40ea-8d4d-dd9e77307e1b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    " # 2.3 绘制ROC曲线，计算auc，度量分类模型的预测能力\n",
    "# ROC曲线以召回率为纵轴，以假正例率为横轴，ROC曲线下的面积为AUC值\n",
    "y_test_predict_proba = model.predict_proba(X_test)\n",
    "false_positive_rate, recall, thresholds = roc_curve(y_test, y_test_predict_proba[:, 1])\n",
    "roc_auc = auc(false_positive_rate, recall)  # 计算auc的值\n",
    "plt.figure()\n",
    "plt.title('%s 模型的 ROC-AUC 图' % model_name)\n",
    "plt.plot(false_positive_rate, recall, 'r', label='AUC = %0.3f' % roc_auc)\n",
    "plt.legend(loc='best')\n",
    "plt.plot([0, 1], [0, 1], 'k--')\n",
    "plt.xlim([0.0, 1.0])\n",
    "plt.ylim([0.0, 1.0])\n",
    "plt.ylabel('真正例率(召回率)')\n",
    "plt.xlabel('假正例率')\n",
    "plt.savefig('./results/ROC_AUC_with_model_{}.png'.format(model_name))\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "12a2be81-bfdf-4f90-9610-1b1884c3de32",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
